bitkeeper revision 1.1159.258.83 (424c1abd7LgWMiaskLEEAAX7ffdkXQ)
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Thu, 31 Mar 2005 15:43:57 +0000 (15:43 +0000)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Thu, 31 Mar 2005 15:43:57 +0000 (15:43 +0000)
Backport of batched request_queue unplugging in blkback driver.
Signed-off-by: Keir Fraser <keir@xensource.com>
linux-2.6.11-xen-sparse/drivers/xen/blkback/blkback.c
linux-2.6.11-xen-sparse/drivers/xen/blkback/common.h
linux-2.6.11-xen-sparse/drivers/xen/blkback/vbd.c

index 1f117e21ddc25dac65fe1a2bbf39a6588f25a759..9fb789216c6a8ff7d97c5f90de7a7c9a1bc4f752 100644 (file)
@@ -66,6 +66,19 @@ static PEND_RING_IDX pending_prod, pending_cons;
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
 static kmem_cache_t *buffer_head_cachep;
+#else
+static request_queue_t *plugged_queue;
+void bdev_put(struct block_device *bdev)
+{
+    request_queue_t *q = plugged_queue;
+    /* We might be giving up last reference to plugged queue. Flush if so. */
+    if ( (q != NULL) &&
+         (q == bdev_get_queue(bdev)) && 
+         (cmpxchg(&plugged_queue, q, NULL) == q) )
+        blk_run_queue(q);
+    /* It's now safe to drop the block device. */
+    blkdev_put(bdev);
+}
 #endif
 
 static int do_block_io_op(blkif_t *blkif, int max_to_do);
@@ -176,9 +189,15 @@ static int blkio_schedule(void *arg)
             blkif_put(blkif);
         }
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
         /* Push the batch through to disc. */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
         run_task_queue(&tq_disk);
+#else
+        if ( plugged_queue != NULL )
+        {
+            blk_run_queue(plugged_queue);
+            plugged_queue = NULL;
+        }
 #endif
     }
 }
@@ -481,6 +500,7 @@ static void dispatch_rw_block_io(blkif_t *blkif, blkif_request_t *req)
     for ( i = 0; i < nr_psegs; i++ )
     {
         struct bio *bio;
+        request_queue_t *q;
 
         bio = bio_alloc(GFP_ATOMIC, 1);
         if ( unlikely(bio == NULL) )
@@ -500,7 +520,14 @@ static void dispatch_rw_block_io(blkif_t *blkif, blkif_request_t *req)
             phys_seg[i].nr_sects << 9,
             phys_seg[i].buffer & ~PAGE_MASK);
 
-        submit_bio(operation | (1 << BIO_RW_SYNC), bio);
+        if ( (q = bdev_get_queue(bio->bi_bdev)) != plugged_queue )
+        {
+            if ( plugged_queue != NULL )
+                blk_run_queue(plugged_queue);
+            plugged_queue = q;
+        }
+
+        submit_bio(operation, bio);
     }
 #endif
 
index 4a12ca8fe9644184aa5d3368c1462ec29244d3f0..8f8a5217025594c093f241b4b53c3b17bf10a9f6 100644 (file)
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
 typedef struct rb_root rb_root_t;
 typedef struct rb_node rb_node_t;
+extern void bdev_put(struct block_device *bdev);
 #else
 struct block_device;
+#define bdev_put(_b) ((void)0)
 #endif
 
 typedef struct blkif_st {
index 1aa5acf0c9c7270b0f747827f93c65ced1d1150b..639b8fc5d5b2c4ca074cf24969073fa05f4658f5 100644 (file)
@@ -150,7 +150,7 @@ void vbd_grow(blkif_be_vbd_grow_t *grow)
     {
         DPRINTK("vbd_grow: device %08x doesn't exist.\n", x->extent.device);
         grow->status = BLKIF_BE_STATUS_EXTENT_NOT_FOUND;
-        blkdev_put(x->bdev);
+        bdev_put(x->bdev);
         goto out;
     }
 
@@ -255,7 +255,7 @@ void vbd_shrink(blkif_be_vbd_shrink_t *shrink)
     *px = x->next; /* ATOMIC: no need for vbd_lock. */
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-    blkdev_put(x->bdev);
+    bdev_put(x->bdev);
 #endif
     kfree(x);
 
@@ -307,7 +307,7 @@ void vbd_destroy(blkif_be_vbd_destroy_t *destroy)
     {
         t = x->next;
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-        blkdev_put(x->bdev);
+        bdev_put(x->bdev);
 #endif
         kfree(x);
         x = t;
@@ -335,7 +335,7 @@ void destroy_all_vbds(blkif_t *blkif)
         {
             t = x->next;
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-            blkdev_put(x->bdev);
+            bdev_put(x->bdev);
 #endif
             kfree(x);
             x = t;